﻿using Autofac.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace QuartzServiceApp
{
    class ProgramRunner: IHostedService
    {
        private readonly ILogger<GreetingService> logger;
        private readonly IConfiguration _config;
        private readonly IServiceProvider autofacServiceProvider;
        //private readonly ExampleSettings _exampleSettings;

        //public GreetingService(ILogger<GreetingService> log, IConfiguration config, ExampleSettings exampleSettings)
        public ProgramRunner(ILogger<GreetingService> log, IConfiguration config, IServiceProvider autofacServiceProvider)
        {
            logger = log;
            _config = config;
            this.autofacServiceProvider = autofacServiceProvider;
            //_exampleSettings = exampleSettings;
        }
        //public Task StartAsync(CancellationToken cancellationToken)
        //{
        //    Console.WriteLine("服务已启动");
        //    // 在这里添加你的启动逻辑
        //    return Task.CompletedTask;
        //}

        //public Task StopAsync(CancellationToken cancellationToken)
        //{
        //    Console.WriteLine("服务已停止");
        //    // 在这里添加你的停止逻辑
        //    return Task.CompletedTask;
        //}
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            var pre = "###";
            var jobInfos = JsonConfig.Get<CronJob>("CronJob.json")?.JobInfos;
            //check json file
            if (jobInfos == null)
            {
                logger.LogInformation($"{pre}get assemly error,please check JsonConfig/CronJob.json");
                logger.LogInformation($"{pre}no job loaded");
                return;
            }

            //check samejobs
            var sameJobs = from j in jobInfos.Where(x => x.Enable == true)
                           group j by j.JobName into g
                           select new { c = g.Count(), j = g.Key };

            if (sameJobs.Where(x => x.c > 1).Any())
            {
                logger.LogInformation($"{pre}exist same jobname:{string.Join(",", sameJobs.Where(x => x.c > 1).Select(x => x.j))},");
                logger.LogInformation($"{pre}all job loaded fail!");
                return;
            }

            var loadLog = new StringBuilder();
            loadLog.AppendLine($"");

            var successful = 0;

            var enableInfos = jobInfos.Where(w => w.Enable == true).ToList();

            for (int i = 1; i <= enableInfos.Count; i++)
            {
                var jobInfo = enableInfos[i - 1];
                var type = AutofacHelper.GetAssemlyJobs(autofacServiceProvider,jobInfo.JobName);
                if (type != null)
                {
                    var cronDescription = jobInfo.Cron.CronDescription();

                    if (cronDescription != "#")
                    {
                        successful++;
                        await QuartzManager.AddJobAsync(type, jobInfo.Cron);
                        loadLog.AppendLine($"{pre}[{i}] load job successful,job name:{jobInfo.JobName},corn:{jobInfo.Cron}->[{cronDescription}]");
                    }
                    else
                    {
                        loadLog.AppendLine($"{pre}[{i}] load job error,corn error,job name:{jobInfo.JobName},corn:{jobInfo.Cron}");
                    }
                }
                else
                {
                    loadLog.AppendLine($"{pre}[{i}] load job error,no assemlyjob,job name :{jobInfo.JobName}");
                }
            }
            loadLog.AppendLine($"{pre}loaded all job,total/successful/error:{jobInfos.Count}/{successful}/{jobInfos.Count - successful}");

            logger.LogInformation(loadLog.ToString());
        }

        //public Task StartAsync(CancellationToken cancellationToken)
        //{
        //    throw new NotImplementedException();
        //}

        public async Task StopAsync(CancellationToken cancellationToken)
        {
            await QuartzManager.ShutdownAllAsync();
        }

        //public Task StopAsync(CancellationToken cancellationToken)
        //{
        //    throw new NotImplementedException();
        //}

        //public async Task ContinueAsync(HostControl hostControl)
        //{
        //    await QuartzManager.ResumeAllAsync();
        //}

        //public async Task Pause(HostControl hostControl)
        //{
        //    await QuartzManager.PauseAllAsync();
        //}
    }

}
